#include <my_header.h>
#if 0
以一个卖票的逻辑为例:
// 一个人卖票: 票未必每一次都能卖掉, 每一次买票的人在
// 随机的状态下选择是否买票
// 另一个人加票
// 在初始20张票的情况下:每次卖一张
// 当第一次票小于5张的时候再追加一次票: 10张票
#endif
/* Usage: ./21_sell_ticket */
// 失败示例
typedef struct share_state
{
    int ticketNum;
    int flag;   // 0未加票，1已加票
    pthread_mutex_t mLock;
    pthread_cond_t cond;    // 条件变量
}share_state_t;
void *sellFun(void *arg)
{
    // 创建结构体对象
    share_state_t *pShareState = (share_state_t *)arg;
    while(1){
        pthread_mutex_lock(&pShareState->mLock);
        if(pShareState->ticketNum <= 0 && pShareState->flag !=0)
        {   // 票数小于0且已加票   
            pthread_mutex_unlock(&pShareState->mLock);
            break;
        }
        // 获取当前的时间 并添加随机数判断条件
        struct timeval nowTime;
        gettimeofday(&nowTime, NULL);
        srand((unsigned int)nowTime.tv_usec);
        // 通过 rand() / (double)RAND_MAX，使得返回值在 0 到 1 之间。
        double rand_num = (double)rand()/RAND_MAX;

        // 开始卖票
        if(pShareState->ticketNum > 0 && rand_num<0.5)
        {
            pShareState->ticketNum--;
            printf("ticketNum = %d\n", pShareState->ticketNum);
        }

        // 票数小于5并且未加票
        if(pShareState->ticketNum <=5 && pShareState->flag == 0)
        {
            // 发送信号已加票
            pthread_cond_signal(&pShareState->cond);
            // 等待卖票的发送解除阻塞
            pthread_cond_wait(&pShareState->cond,
                              &pShareState->mLock);
        }
        pthread_mutex_unlock(&pShareState->mLock);
    }
    return NULL;
}
// 加票
void *purchaseFun(void *arg)
{
    share_state_t *pShareState = (share_state_t *)arg;

    pthread_mutex_lock(&pShareState->mLock);
    // 票数少于5加票
    if(pShareState->ticketNum > 5){
        pthread_cond_wait(&pShareState->cond,
                          &pShareState->mLock);
        pShareState->ticketNum = pShareState->ticketNum + 10;
        pShareState->flag = 1;
    }else{
        pShareState->ticketNum = pShareState->ticketNum+10;
        pShareState->flag = 1;
    }
    pthread_cond_signal(&pShareState->cond);
    pthread_mutex_unlock(&pShareState->mLock);

    return NULL;
}

int main(void){                                  
    // 创建结构体对象
    share_state_t shareState;
    // 初始化票数和锁
    shareState.ticketNum = 20;
    shareState.flag = 0;
    pthread_mutex_init(&shareState.mLock, NULL);
    pthread_cond_init(&shareState.cond, NULL);
    // 创建子线程
    pthread_t tid1, tid2;
    int ret_create1 = pthread_create(&tid1, NULL, sellFun, &shareState);
    THREAD_ERROR_CHECK(ret_create1, "pthread_create1");
    int ret_create2 = pthread_create(&tid2, NULL, purchaseFun, &shareState);
    THREAD_ERROR_CHECK(ret_create2, "pthread_create2");

    // 捕获、阻塞 并清理资源
    int ret_join1 = pthread_join(tid1, NULL);
    THREAD_ERROR_CHECK(ret_join1, "pthread_join1");
    int ret_join2 = pthread_join(tid2, NULL);
    THREAD_ERROR_CHECK(ret_join2, "pthread_join2");

    return 0;
}


